home *** CD-ROM | disk | FTP | other *** search
- /* $Revision Header *** Header built automatically - do not edit! ***********
- *
- * (C) Copyright 1993 by Rainer Koppler
- *
- * Name .....: APCNames.c
- * Created ..: Friday 5-Mar-93 19:31:41
- * Revision .: 6
- *
- * Date Author Comment
- * ========= ==================== ====================
- * 07-Dec-93 Rainer Koppler enhanced encoding of long names
- * 23-Sep-93 Rainer Koppler "S:APCNames.types" support added
- * 09-Sep-93 Rainer Koppler Symantec C++ support added
- * 15-Jul-93 Rainer Koppler MS-Word support added
- * 23-Mar-93 Rainer Koppler Bug fix: multiple periods handled
- * 17-Mar-93 Rainer Koppler Bug fix: disk entry only at root level
- * 05-Mar-93 Rainer Koppler Created this file!
- *
- ****************************************************************************
- *
- * Utility for creating original file names for MS-DOS file names
- * from the APCINFO.DAT file created by the Mac tool AccessPC.
- *
- * $Revision Header ********************************************************/
-
- #include "APCNames.h"
- #include "Types.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- #ifndef AMIGA
- extern int strnicmp (char *, char *, int);
- extern int stricmp (char *, char *);
- #endif
-
- /*-------------------------------------------------------------------
- ** SetPattern/NextEntry are my own Amiga-specific pattern-matching
- ** routines. I suppose there is no need for them for UNIX... :^)
- **-------------------------------------------------------------------
- */
-
- #ifdef AMIGA
- #include "Wildcard.h"
- #else
- #ifndef SEEK_SET
- #define SEEK_SET 0
- #define SEEK_CUR 1
- #define SEEK_END 2
- #endif
- #ifndef EXIT_FAILURE
- #define EXIT_FAILURE 1
- #endif
- static char *fnDummy;
- static void SetPattern (char *fileName)
- {
- fnDummy = fileName;
- }
- static char *NextEntry (void)
- {
- char *fn = fnDummy;
- fnDummy = NULL;
- return fn;
- }
- #endif
-
-
- /*-------------------------------------------------------------------
- ** Each APCINFO.DAT file consists of several records denoting
- ** disk or file entries. Each record has a length of 80 bytes.
- ** The first record always denotes a disk entry, all subsequent
- ** records are file entries.
- ** After each 12 entries there are 64 bytes with undefined contents.
- **-------------------------------------------------------------------
- */
-
- #define APC_ENTRY_SIZE sizeof(union APCEntry)
- #define APC_PAD_SIZE 0x40
-
- union APCEntry {
-
- UBYTE ae_Data[80];
-
- struct DiskEntry {
- UBYTE de_Length; /*length of disk name*/
- UBYTE de_Pad[79]; /*disk name and other data*/
- } de;
-
- struct FileEntry {
- UBYTE fe_Length; /*length of file name*/
- char fe_Name[31]; /*file name characters*/
- ULONG fe_Type; /*Macintosh type ID*/
- ULONG fe_Creator; /*Macintosh creator ID*/
- UBYTE fe_Pad1[23]; /*undocumented data*/
- UBYTE fe_Flags; /*file visible <=> 0 (?)*/
- char fe_MSDOSName[8]; /*file name padded with blanks*/
- char fe_MSDOSExt[3]; /*extension padded with blanks*/
- UBYTE fe_Pad2[5]; /*always zero*/
- } fe;
-
- };
-
-
- /*----------------------------- global data ---------------------------------*/
-
- static FILE *apcInfoDat;
- static union APCEntry *entry,*tstEntry;
- static char lngName[32],shtName[13],*sptr;
-
- static const char versionStr[] = {
- "\0$VER: APCNames 1.2 by Rainer Koppler (7.12.93)"
- };
-
-
- /*---------------- disk entry for empty disk (view by name) -----------------*/
-
- static ULONG de_Empty[] = {
- 0x0A526169, 0x6E657220, 0x31001600, 0x0002A002,
- 0x02000000, 0x00000000, 0x00000000, 0x00000001,
- 0x002E0008, 0x00EA019C, 0x01000070, 0x02480200,
- 0xFFF8FFF0, 0x00000000, 0x00008000, 0x00000002,
- 0x7FA95F49, 0x6E736967, 0x6E696100, 0x00000000
- };
-
- /*------------------------- universal file entry ----------------------------*/
-
- static ULONG fe_Default[] = {
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x000D0D90, 0x0000000F, 0x000000E5, 0x000D0D90,
- 0x00000000, 0x00000000, 0x0100FFFF, 0xFFFF0000, /* TYPE, CREATOR, ... */
- 0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0x00000000
- };
-
-
- /*---------------------------------------------------------------------------*/
-
- static void Pas2CStr (UBYTE *ps, char *cs)
- {
- UBYTE len = *ps;
-
- strncpy(cs,(char *)ps+1,len);
- *(cs+len) = '\0';
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void C2PasStr (char *cs, UBYTE *ps)
- {
- UBYTE len = strlen(cs);
-
- strcpy((char *)ps+1,cs);
- *ps = len;
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void Long2Short (char *fileName)
- {
- char *dotPtr,*lptr,ch,orgCh;
- struct TCInfo *tci;
- int i,stubIdx,state;
- LONG fp;
-
- /*--- copy entry template to "entry" and insert TYPE/CREATOR ---*/
- memcpy(entry,fe_Default,APC_ENTRY_SIZE);
- tci = TCInfoFor(fileName);
- entry->fe.fe_Type = tci->tci_Type;
- entry->fe.fe_Creator =tci->tci_Creator;
- /*--- insert original file name ---*/
- C2PasStr(fileName,(UBYTE *)entry);
- /*--- 1. encode original file name to "shtName" (MS-DOS format) ---*/
- for(i=0,sptr=shtName,lptr=fileName; i<8 && *lptr!='\0' && *lptr!='.';
- sptr++,lptr++,i++)
- *sptr = toupper(*lptr);
- stubIdx = lptr-fileName; /* where the stub character would be placed */
- if(stubIdx == 8) stubIdx--;
- dotPtr = strchr(fileName,'.');
- if(dotPtr) {
- for(; i<8; i++,sptr++) *sptr = ' ';
- for(lptr=dotPtr+1; i<11 && *lptr!='\0'; lptr++)
- if(*lptr != '.') {
- *sptr = toupper(*lptr);
- sptr++;
- i++;
- }
- }
- for(; i<11; i++,sptr++) *sptr = ' ';
- /*--- 2. seek existing entry with same MS-DOS name & modify new name if so ---*/
- fseek(apcInfoDat,0L,SEEK_SET);
- state = 0;
- orgCh = shtName[stubIdx];
- while(fread(tstEntry,APC_ENTRY_SIZE,1,apcInfoDat) > 0) {
- if(!strncmp(tstEntry->fe.fe_MSDOSName,shtName,11)) {
- do {
- if(state == 0)
- ch = '&';
- else if(state>=1 && state<=10)
- ch = '0'+state-1;
- else if(state>=11 && state<=36)
- ch = 'A'+state-11;
- else {
- printf("*** Encoding possibilities exceeded. Try to rename some files.\n");
- exit(EXIT_FAILURE);
- }
- state++;
- } while(ch == orgCh);
- shtName[stubIdx] = ch;
- }
- fp = ftell(apcInfoDat);
- if(fp % 0x0400 == 0x03C0)
- fread(tstEntry,APC_PAD_SIZE,1,apcInfoDat);
- }
- /*--- 3. insert MS-DOS file name into entry & prepare "shtName" for rename ---*/
- for(i=0,sptr=shtName,lptr=entry->fe.fe_MSDOSName; i<11; i++,sptr++,lptr++)
- *lptr = *sptr;
- for(i=0,sptr=shtName,lptr=entry->fe.fe_MSDOSName; i<11; i++) {
- if(i==8 && dotPtr && *(dotPtr+1)) {
- *sptr = '.';
- sptr++;
- }
- if(*lptr != ' ') {
- *sptr = *lptr;
- sptr++;
- }
- lptr++;
- }
- *sptr = 0;
- }
-
- /*---------------------------------------------------------------------------*/
-
- static void Short2Long (void)
- {
- int i;
- char *ptr;
-
- if(entry->fe.fe_Length > 31) {
- *shtName = '\0'; *lngName = '\0';
- return;
- }
- Pas2CStr((UBYTE *)entry,lngName);
- sptr = shtName;
- ptr = entry->fe.fe_MSDOSName;
- for(i=0; i<8 && *ptr!=' '; sptr++,ptr++,i++)
- *sptr = *ptr;
- ptr = entry->fe.fe_MSDOSExt;
- if(*ptr != ' ') {
- *sptr = '.';
- sptr++;
- }
- for(i=0; i<3 && *ptr!=' '; sptr++,ptr++,i++)
- *sptr=*ptr;
- *sptr = '\0';
- }
-
- /*---------------------------------------------------------------------------*/
-
- static BOOL EntryExistsFor (char *fileName)
- {
- BOOL fnd = FALSE;
- LONG fp;
-
- fseek(apcInfoDat,0L,SEEK_SET);
- while(!fnd && fread(entry,APC_ENTRY_SIZE,1,apcInfoDat) > 0) {
- Pas2CStr((UBYTE *)entry,lngName);
- if(!(fnd = !stricmp(fileName,lngName))) {
- fp = ftell(apcInfoDat);
- if(fp % 0x0400 == 0x03C0)
- fread(entry,APC_PAD_SIZE,1,apcInfoDat);
- }
- }
- return(fnd);
- }
-
- /*---------------------------------------------------------------------------*/
-
- main (int argc, char *argv[])
- {
- int cnt,fnCnt,total,cIdx;
- char *fn,cmdBuf[80];
- LONG fp;
- BOOL err = FALSE,cpyFiles = FALSE;
-
- printf("\n»»APCNames«« - AccessPC renaming utility v1.2 for UNIX\n\n");
-
- if(--argc > 0) {
- err = argc==1 && strcmp(argv[1],"-x") ;
- if(!err) err = argc==2 && strncmp(argv[1],"-c",2);
- if(!err) err = argc>2 && strncmp(argv[1],"-c",2) && (strcmp(argv[1],"-x") &&
- strncmp(argv[2],"-c",2));
- cpyFiles = !strcmp(argv[1],"-x");
- }
-
- if(err) {
- printf("USAGE: %s [ -x ][ -c[<config>] <file> { <file> }]\n",argv[0]);
- exit(EXIT_FAILURE);
- }
-
- if(!(entry=malloc(APC_ENTRY_SIZE*2))) {
- printf("*** No memory for entry blocks.\n");
- exit(EXIT_FAILURE);
- }
- tstEntry = entry+APC_ENTRY_SIZE;
-
- fnCnt = 0;
- total = 0;
-
- /*--- transform long names to short names and create/update APCINFO file ---*/
- if(argc > 1) {
- cIdx = strcmp(argv[1],"-x") ? 1 : 2;
- if(!(apcInfoDat=fopen("APCINFO.DAT","a+"))) {
- printf("*** Cannot open APCINFO.DAT for update.\n");
- exit(EXIT_FAILURE);
- }
- /*--- if new file then create (empty) disk entry at beginning ---*/
- fseek(apcInfoDat,0L,SEEK_END);
- if(ftell(apcInfoDat) == 0)
- fwrite(de_Empty,1,APC_ENTRY_SIZE,apcInfoDat);
- /*--- configuration file specified ? ---*/
- if(strlen(argv[cIdx]) > 2)
- ReadTypes(argv[cIdx]+2);
- else
- ReadTypes(DEFAULT_CONFIG);
- /*--- process file patterns ---*/
- for(cnt=cIdx+1; cnt<=argc; cnt++) {
- SetPattern(argv[cnt]);
- while(fn = NextEntry()) {
- /*--- lookup APCINFO.DAT for existing entry ---*/
- if(!EntryExistsFor(fn)) {
- fseek(apcInfoDat,0L,SEEK_END);
- fp = ftell(apcInfoDat);
- if(fp % 0x0400 == 0x03C0) {
- memset(tstEntry,0,APC_PAD_SIZE);
- fwrite(tstEntry,APC_PAD_SIZE,1,apcInfoDat);
- }
- Long2Short(fn);
- fwrite(entry,APC_ENTRY_SIZE,1,apcInfoDat);
- }
- else {
- printf("\"%s\" already exists, ",fn);
- Short2Long();
- }
- if(cpyFiles) {
- printf("writing \"%s\" as \"%s\" to DOS disk...",fn,shtName);
- sprintf(cmdBuf,"mwrite %s %s",fn,shtName);
- if(!system(cmdBuf)) {
- printf("ok\n");
- fnCnt++;
- }
- else
- printf("failed\n");
- }
- else {
- printf("renaming \"%s\" to \"%s\"...",fn,shtName);
- if(!rename(fn,shtName)) {
- printf("ok\n");
- fnCnt++;
- }
- else
- printf("failed\n");
- }
- total++;
- }
- }
- fclose(apcInfoDat);
- printf("\n%d file(s) of %d renamed successfully.\n",fnCnt,total);
- if(cpyFiles && system("mwrite APCINFO.DAT APCINFO.DAT"))
- printf("*** Cannot write APCINFO.DAT to DOS disk.\n");
- }
- /*--- get contents of APCINFO file and transform short names to long names ---*/
- else {
- if(cpyFiles && system("mread APCINFO.DAT APCINFO.DAT"))
- printf("*** Cannot access APCINFO.DAT on DOS disk.\n");
- if(!(apcInfoDat=fopen("APCINFO.DAT","r"))) {
- printf("*** Cannot open APCINFO.DAT for input.\n");
- exit(EXIT_FAILURE);
- }
- cnt = 0;
- while(fread(entry,APC_ENTRY_SIZE,1,apcInfoDat) > 0) {
- /*--- D I S K E N T R Y ---*/
- if(entry->fe.fe_MSDOSName[1] == '©') {
- Pas2CStr((UBYTE *)entry,lngName);
- printf("Disk name: %s\n\n",lngName);
- }
- /*--- F I L E E N T R Y ---*/
- else {
- /*--- create MS-DOS name and original name of entry data ---*/
- Short2Long();
- /*--- rename only if valid file entry ---*/
- if(entry->fe.fe_Type == TYPE_TEXT || entry->fe.fe_Type == TYPE_WDBN) {
- if(cpyFiles) {
- printf("reading \"%s\" as \"%s\" from DOS disk...",lngName,shtName);
- sprintf(cmdBuf,"mread %s %s",shtName,lngName);
- if(!system(cmdBuf)) {
- printf("ok\n");
- fnCnt++;
- }
- else
- printf("failed\n");
- }
- else {
- printf("renaming \"%s\" to \"%s\"...",shtName,lngName);
- if(!rename(shtName,lngName)) {
- printf("ok\n");
- fnCnt++;
- }
- else
- printf("failed\n");
- }
- total++;
- }
- else
- printf("ignoring \"%s\" (\"%s\")\n",shtName,lngName);
- }
- cnt++;
- /*--- skip 64 bytes after each 12 records ---*/
- if(cnt == 12) {
- fread(entry,APC_PAD_SIZE,1,apcInfoDat);
- cnt = 0;
- }
- }
- fclose(apcInfoDat);
- printf("\n%d file(s) of %d renamed successfully.\n",fnCnt,total);
- }
- FreeTypes();
-
- free(entry);
- }
-